package com.daxiong.commons;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.daxiong.commons.entity.Bean;
import com.daxiong.commons.entity.ClassName;
import com.daxiong.commons.entity.CopyrightInformation;
import com.daxiong.commons.entity.CreateBean;
import com.daxiong.commons.entity.PackageName;
import com.daxiong.commons.entity.Variable;
import com.daxiong.commons.exception.CreateBeanUtilsException;

public class CreateBeanUtils {
    private static final Integer DEFAULT_BUFFER = new Integer(512);
    private static final String ENCODING = new String("UTF-8");
    private static Logger logger = LoggerFactory.getLogger(CreateBeanUtils.class);

    public static void main(String argv[]) {
        final String[] sourcePathArray = { "C:", "Users", "DAXIONG", "test" };
        final String sourcePath = StringUtils.join(sourcePathArray, File.separator);

        execution(sourcePath, null);
    }

    public static void execution(final String sourceDirectoryPath, final CreateBean createBean) {
        logger.info("execution start");

        final Date start = new Date();

        File sourceDirectory = null;
        File outputDirectory = null;

        try {
            final String tempDirectory = "_" + new SimpleDateFormat("yyyyMMddHHmmss").format(start);
            final String outputDirectoryPath = sourceDirectoryPath + File.separator + tempDirectory;

            sourceDirectory = new File(sourceDirectoryPath);
            outputDirectory = new File(outputDirectoryPath);

            logger.info("來源目錄路徑:" + sourceDirectory.getAbsolutePath());
            logger.info("產出目錄路徑:" + outputDirectory.getAbsolutePath());

            if (StringUtils.isBlank(sourceDirectoryPath)) {
                throw new CreateBeanUtilsException("來源目錄路徑不能為空");
            }

            if (!sourceDirectory.exists()) {
                final String messageFormat = "來源目錄路徑不存在[%s]";
                throw new CreateBeanUtilsException(String.format(messageFormat, sourceDirectoryPath));
            }

            if (!sourceDirectory.isDirectory()) {
                final String messageFormat = "來源必須是目錄[%s]";
                throw new CreateBeanUtilsException(String.format(messageFormat, sourceDirectoryPath));
            }

            final File[] sources = sourceDirectory.listFiles();

            if (sources != null && sources.length != 0) {
                outputDirectory.mkdir();

                for (final File source : sources) {
                    if ("java".equals(FilenameUtils.getExtension(source.getAbsolutePath()))) {
                        beanToFile(getBean(source));
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);

            try {
                logger.error("刪除產出目錄:{}", outputDirectory.getAbsolutePath());
                FileUtils.deleteDirectory(outputDirectory);
                logger.error("刪除產出目錄成功");
            } catch (Exception exception) {
                logger.error("刪除產出目錄失敗");
            }

            throw new CreateBeanUtilsException(e);
        } finally {
            logger.info("執行時間：" + (System.currentTimeMillis() - start.getTime()) + "毫秒");

            logger.info("execution end");
        }
    }

    private static Bean getBean(final File file) {
        final Bean bean = new Bean(new ArrayList<Bean>(), new ArrayList<Bean>(), new ArrayList<Variable>());

        try {
            boolean isExplanationBlock = false;
            List<String> explanationContent = new ArrayList<String>();

            final List<?> lines = FileUtils.readLines(file, ENCODING);
            for (final Object object : lines) {
                final String line = StringUtils.trim((String) object);
                final int length = line.length();

                if (StringUtils.isBlank(line)) {
                    isExplanationBlock = false;
                    explanationContent.clear();
                    continue;
                }

                if (!isExplanationBlock) {
                    if (StringUtils.startsWith(line, "//")) {
                        explanationContent.clear();
                        explanationContent.add(line.substring(2, length).trim());
                        continue;
                    }

                    if (StringUtils.startsWith(line, "/*") && StringUtils.endsWith(line, "*/")) {
                        explanationContent.clear();
                        explanationContent.add(line.substring(2, (length - 2)).trim());
                        continue;
                    }

                    if (StringUtils.startsWith(line, "/**") && StringUtils.endsWith(line, "*/")) {
                        explanationContent = new ArrayList<String>();
                        explanationContent.add(line.substring(3, (length - 2)).trim());
                        continue;
                    }

                    if (StringUtils.startsWith(line, "/*") && !StringUtils.endsWith(line, "*/")) {
                        explanationContent.clear();
                        isExplanationBlock = true;
                        continue;
                    }

                    if (StringUtils.startsWith(line, "/**") && !StringUtils.endsWith(line, "*/")) {
                        explanationContent.clear();
                        isExplanationBlock = true;
                        continue;
                    }

                    if (bean.getPackageName() == null && "/*".equals(StringUtils.substring(line, 0, 2))) {
                        new CopyrightInformation();
                        continue;
                    }

                    if (StringUtils.startsWith(line, "package ")) {
                        bean.setPackageName(getPackageName(line));
                        bean.setCopyrightInformation(getCopyrightInformation(explanationContent));
                        explanationContent.clear();
                        continue;
                    }

                    if (StringUtils.startsWith(line, "import ")) {
                        bean.getImportList().add(getImport(line));
                        explanationContent.clear();
                        continue;
                    }

                    if (StringUtils.indexOf(line, " class ") != StringUtils.INDEX_NOT_FOUND) {
                        bean.setExtendsObject(getExtendsObject(line));
                        bean.setImplementsObjectList(getImplementsObjectList(line));
                        bean.setClassName(getClassName(line, explanationContent));
                        explanationContent.clear();
                        continue;
                    }

                    if (StringUtils.startsWith(line, "private ")) {
                        bean.getVariableList().add(getVariable(line, explanationContent));
                        explanationContent.clear();
                        continue;
                    }
                } else {
                    if (StringUtils.endsWith(line, "*/")) {
                        isExplanationBlock = false;
                    } else {
                        explanationContent.add(line.substring(1, length).trim());
                    }
                }
            }
        } catch (Exception e) {
            throw new CreateBeanUtilsException(e);
        }

        return bean;
    }

    private static PackageName getPackageName(final String line) {
        return new PackageName(Arrays.asList(StringUtils.substring(line, 8, line.length() - 1).split("/.")));
    }

    private static Bean getImport(final String line) {
        final List<String> contentList = Arrays.asList(StringUtils.substring(line, 8, line.length() - 1).split("/."));

        return new Bean(null, null);
    }

    private static ClassName getClassName(final String line, final List<String> explanationContent) {
        String content = StringUtils.EMPTY;
        boolean nextIsClassName = false;
        for (final String string : line.split(" ")) {
            if (nextIsClassName) {
                content = string;
                break;
            }
            if ("class".equals(string)) {
                nextIsClassName = true;
            }
        }
        return new ClassName(content, explanationContent);
    }

    private static Variable getVariable(final String line, final List<String> explanationContent) {

        return null;
    }

    private static List<Bean> getImplementsObjectList(final String line) {

        return null;
    }

    private static Bean getExtendsObject(final String line) {

        return null;
    }

    private static CopyrightInformation getCopyrightInformation(final List<String> explanationContent) {

        return null;
    }

    private static void beanToFile(final Bean bean) {
    }

}
